local skynet = require "skynet"
local gg = require "game_utils"
local uu = require "sky_utils"
local log = require "sky_log"
local handle_first = require "handle_first"
local handle_second = require "handle_second"
local handle_third = require "handle_third"
local handle_fourth = require "handle_fourth"
require "def"
local M = {}
math.randomseed(tostring(os.time()):reverse():sub(1, 7))

-------------------------------------------------------------------------------
local player_seat_id = 1
local call_score_team = 1
local begin_seatid = call_score_team
local main_color = 1
local round_ctrl = 2
--local round_ctrl = 14
---[[
local _cards = {
    {
        "梅花2",
        "梅花4",
        "梅花3",
        "梅花8",
        "梅花A",
        "梅花K",
        "梅花9",
        "梅花5",
        "梅花J",
        "梅花Q",
        "梅花6",
        "梅花7",
        "梅花10"
      },
      {
        "方块Q",
        "红桃A",
        "黑桃Q",
        "红桃7",
        "黑桃K",
        "黑桃J",
        "黑桃3",
        "黑桃4",
        "红桃J",
        "黑桃5",
        "黑桃8",
        "黑桃9",
        "红桃Q"
      },
      {
        "红桃2",
        "红桃3",
        "黑桃7",
        "红桃5",
        "黑桃10",
        "方块2",
        "方块A",
        "方块K",
        "红桃6",
        "方块4",
        "方块5",
        "红桃8",
        "红桃9"
      },
      {
        "红桃4",
        "红桃10",
        "黑桃A",
        "红桃K",
        "黑桃6",
        "黑桃2",
        "方块3",
        "方块6",
        "方块7",
        "方块J",
        "方块10",
        "方块9",
        "方块8"
      }
    }
--[[
local _cards = {
    {
      "红桃5",
      "红桃9",
      "红桃A",
      "黑桃2",
      "梅花Q",
      "梅花10",
      "梅花K",
      "梅花3",
      "红桃4",
      "红桃8",
      "黑桃7",
      "方块2",
      "梅花5"
    },
    {
      "方块6",
      "黑桃3",
      "红桃J",
      "黑桃Q",
      "梅花J",
      "黑桃4",
      "红桃Q",
      "梅花A",
      "梅花6",
      "方块8",
      "方块4",
      "红桃3",
      "黑桃8"
    },
    {
      "红桃K",
      "红桃2",
      "方块10",
      "梅花2",
      "红桃7",
      "方块5",
      "黑桃10",
      "方块7",
      "梅花8",
      "方块A",
      "黑桃6",
      "方块9",
      "黑桃9"
    },
    {
      "红桃6",
      "方块K",
      "方块J",
      "方块Q",
      "梅花7",
      "梅花9",
      "黑桃J",
      "红桃10",
      "黑桃A",
      "黑桃5",
      "黑桃K",
      "梅花4",
      "方块3"
    }
  }  
--]]
-------------------------------------------------------------------------------
--扑克数据
local _PUKE_CARDS_ = {
    --方块
	["方块2"]=0x0102, ["方块3"]=0x0103, ["方块4"]=0x0104, ["方块5"]=0x0105, ["方块6"]=0x0106, ["方块7"]=0x0107, 
    ["方块8"]=0x0108, ["方块9"]=0x0109, ["方块10"]=0x010A, ["方块J"]=0x010B, ["方块Q"]=0x010C, ["方块K"]=0x010D, 
    ["方块A"]=0x010E,
    --梅花
	["梅花2"]=0x0202, ["梅花3"]=0x0203, ["梅花4"]=0x0204, ["梅花5"]=0x0205, ["梅花6"]=0x0206, ["梅花7"]=0x0207, 
    ["梅花8"]=0x0208, ["梅花9"]=0x0209, ["梅花10"]=0x020A, ["梅花J"]=0x020B, ["梅花Q"]=0x020C, ["梅花K"]=0x020D, 
    ["梅花A"]=0x020E,
    --红桃
    ["红桃2"]=0x0302, ["红桃3"]=0x0303, ["红桃4"]=0x0304, ["红桃5"]=0x0305, ["红桃6"]=0x0306, ["红桃7"]=0x0307, 
    ["红桃8"]=0x0308, ["红桃9"]=0x0309, ["红桃10"]=0x030A, ["红桃J"]=0x030B, ["红桃Q"]=0x030C, ["红桃K"]=0x030D, 
    ["红桃A"]=0x030E,
    --黑桃
    ["黑桃2"]=0x0402, ["黑桃3"]=0x0403, ["黑桃4"]=0x0404, ["黑桃5"]=0x0405, ["黑桃6"]=0x0406, ["黑桃7"]=0x0407, 
    ["黑桃8"]=0x0408, ["黑桃9"]=0x0409, ["黑桃10"]=0x040A, ["黑桃J"]=0x040B, ["黑桃Q"]=0x040C, ["黑桃K"]=0x040D, 
    ["黑桃A"]=0x040E,
}

local history

local function reset_history()
    history = {
        outcard_history = {},
        outcard_history_more = {},
        record_no_color_t = {
            [1] = {
                friend_no_color_t = {},
                enemy_no_color_t = {},
            },
            [2] = {
                friend_no_color_t = {},
                enemy_no_color_t = {},
            },
            [3] = {
                friend_no_color_t = {},
                enemy_no_color_t = {},
            },
            [4] = {
                friend_no_color_t = {},
                enemy_no_color_t = {},
            },
        },
        current_round = 1,
        round_color = nil,
    }
end

local function get_handcards(seatid, cards)
    local t = cards[seatid]
    local ret_t = {}
    for _, v in pairs(t) do
        table.insert(ret_t, _PUKE_CARDS_[v])
    end

    return ret_t
end

local function set_history(the_outchard_seatid, the_outchard, cards)
    table.insert(history.outcard_history, the_outchard)
    local t = {
        seatid = the_outchard_seatid,
        outcard = the_outchard,
    }

    local the_color = uu.calc_card_color(the_outchard)

    --是否检测玩家没有某种花色
    local check_flag = true
    --手牌详细数据记录
    local round = #history.outcard_history_more
    --第一回合第一位玩家出牌
    if not history.outcard_history_more[round] then 
        check_flag = false
        round = 1
        history.outcard_history_more[round] = {}
        --每回合第一个玩家出牌时记录花色
        history.round_color = the_color
    end

    --每回合固定只会记录4次，过了4次就一定是下一回合的出牌了
    if #(history.outcard_history_more[round])==4 then 
        check_flag = false
        round = round + 1
        history.outcard_history_more[round] = {}
        --每回合第一个玩家出牌时记录花色
        history.round_color = the_color
        history.current_round = history.current_round + 1
       
    end
    table.insert(history.outcard_history_more[round], t)

    --无花色记录
    local color = uu.calc_card_color(the_outchard)
    if check_flag==true then 
        --本次出牌和每回合第一张出牌花色对比即可知道其是否还有该种花色
        local round_color = uu.calc_card_color(history.outcard_history_more[round][1].outcard)
        if color~=round_color then
            for i=1, 4 do
                if uu.check_is_friend(i, the_outchard_seatid) then
                    history.record_no_color_t[i].friend_no_color_t[round_color] = true
                else
                    if i~=the_outchard_seatid then
                        history.record_no_color_t[i].enemy_no_color_t[round_color] = true
                    end
                end
            end
        end
    end

    --log.info("history.outcard_history=", history.outcard_history)
    for i=1, 4 do
        local handcards = get_handcards(i, cards)
        local left_n = uu.history_check_color_left_cards_count(handcards, color, history.outcard_history)
        if left_n==0 then
            history.record_no_color_t[i].friend_no_color_t[color] = true
            history.record_no_color_t[i].enemy_no_color_t[color] = true
        end
    end
end

--洗牌
local function rand_cards(the_cards_t)
    for k, v in pairs(the_cards_t) do
        local index = math.random(1, #the_cards_t) 
        local temp = the_cards_t[k]
        the_cards_t[k] = the_cards_t[index]
        the_cards_t[index] = temp
    end
    --再洗一次
    for k, v in pairs(the_cards_t) do
        local index = math.random(1, #the_cards_t) 
        local temp = the_cards_t[k]
        the_cards_t[k] = the_cards_t[index]
        the_cards_t[index] = temp
    end
end

local function get_next_player(prev_outcard_seat_id)
    if not prev_outcard_seat_id then
        return begin_seatid
    end

    local next_seatid = (prev_outcard_seat_id + 1) % 4
    if next_seatid==0 then
        next_seatid = 4
    end

    return next_seatid
end

local function compare_cards()
    local round_history = history.outcard_history_more[history.current_round]
    local max_info = {}
    for _, v in pairs(round_history) do
        if max_info.card==nil then
            max_info.card = v.outcard
            max_info.seat_id = v.seatid
        else
            local the_color = uu.calc_card_color(max_info.card)
            local _color = uu.calc_card_color(v.outcard)
            if the_color==_color then
                local the_value = uu.calc_card_value(max_info.card)
                local _value = uu.calc_card_value(v.outcard)
                if _value > the_value then
                    max_info.card = v.outcard
                    max_info.seat_id = v.seatid
                end
            else
                if _color==main_color then
                    max_info.card = v.outcard
                    max_info.seat_id = v.seatid
                end
            end
        end
    end

    return max_info.seat_id
end

local function check_is_call_score_team(seatid)
    --[[
    for _, v in pairs(call_score_team) do
        if v==seatid then
            return true
        end
    end
    --]]

    return false
end

local function remove_outcard(seatid, the_card, cards)
    local t = cards[seatid]
    for k, v in pairs(t) do
        if the_card==_PUKE_CARDS_[v] then
            table.remove(t, k)
            break
        end
    end
end

local function outcard_logic(seatid, cards)
    --是否叫分队
    --local is_call_score_team = check_is_call_score_team(seatid)
    --是否叫分队
    local is_call_score_team = uu.check_is_friend(call_score_team, seatid)
    if call_score_team==seatid then
        is_call_score_team = true
    end

    --上一回合第一个出牌的椅子号
    local last_round_first_outcard_seatid = gg.get_last_round_first_outcard_seatid(history.outcard_history_more)
    --玩家是否是上回合第一个出牌的
    local is_first_out_last_round = (last_round_first_outcard_seatid == seatid)
    --得到上一回合自己出的牌
    local last_round_outcard = gg.get_last_round_self_outcard(history.outcard_history_more, seatid)
    --第几位出牌
    local pos
    if next(history.outcard_history_more) then
        pos = gg.calc_round_pos(history.outcard_history_more)
    else
        pos = 1
    end
    --上一玩家出的牌
    local prev_card = gg.get_prev_outcard(history.outcard_history_more)
    local handcards = get_handcards(seatid, cards)

    local outcard
    if seatid == player_seat_id then
        outcard = _PUKE_CARDS_[cards[seatid][1]]
    else
        if pos==1 then 
            outcard = handle_first.do_card(handcards, is_call_score_team, main_color,
                history.outcard_history, history.record_no_color_t[seatid].enemy_no_color_t,
                history.record_no_color_t[seatid].friend_no_color_t,
                history.current_round, is_first_out_last_round, last_round_outcard,
                history.outcard_history_more, seatid)
        elseif pos==2 then
            outcard = handle_second.do_card(handcards, main_color, history.round_color,
                prev_card, history.outcard_history, history.record_no_color_t[seatid].enemy_no_color_t, 
                history.outcard_history_more, seatid)
        elseif pos==3 then
            outcard = handle_third.do_card(handcards, main_color, history.round_color,
                history.record_no_color_t[seatid].enemy_no_color_t, history.outcard_history, 
                history.outcard_history_more, seatid)
        elseif pos==4 then
            outcard = handle_fourth.do_card(handcards, main_color, history.round_color,
                history.record_no_color_t[seatid].enemy_no_color_t, history.outcard_history, 
                history.outcard_history_more, seatid)
        end
    end

    remove_outcard(seatid, outcard, cards)

    local outcard_info = {
        outcard = outcard,
        seatid = seatid,
        pos = pos
    }

    return outcard_info
end

local function do_test_logic()
    history = {
        outcard_history = {},
        outcard_history_more = {},
        record_no_color_t = {
            [1] = {
                friend_no_color_t = {},
                enemy_no_color_t = {},
            },
            [2] = {
                friend_no_color_t = {},
                enemy_no_color_t = {},
            },
            [3] = {
                friend_no_color_t = {},
                enemy_no_color_t = {},
            },
            [4] = {
                friend_no_color_t = {},
                enemy_no_color_t = {},
            },
        },
        current_round = 1,
        round_color = nil,
    }

    local the_cards = {}
    for _, v in pairs(PUKE_CARDS) do
        table.insert(the_cards, v)
    end

    local test_t = {}
    rand_cards(the_cards)
    for i=1, 4 do
        for j=1, 13 do
            local one_card = table.remove(the_cards)
            if not test_t[i] then
                   test_t[i] = {}
            end
            table.insert(test_t[i], one_card)
        end
    end

    local _t = {
        [1] = "方块",
        [2] = "梅花",
        [3] = "红桃",
        [4] = "黑桃",
    }
    log.warning("--------------------------------------------------------------")
    log.warning("牌局设定：", " 叫分玩家(开始玩家座位号):"..call_score_team.." 主花色:".._t[main_color])
    --log.warning("cards=", test_t)
    M.test_logic(test_t)
end

function M.test_logic(cards)
    cards = cards or _cards
    local do_logic = true
    local outcard_seat_id

    reset_history()
    while do_logic do
        local round = history.current_round
        if not history.outcard_history_more 
        or not history.outcard_history_more[round] then
            round = 1
            log.info("current_round: 1")
        else
            --每回合固定只会记录4次，过了4次就一定是下一回合的出牌了
            if #(history.outcard_history_more[round])==4 then
                if (round+1)==round_ctrl then
                    break
                end
                log.info("current_round: ", round+1)
            end
        end

        local next_seatid = get_next_player(outcard_seat_id)
        local current_round = #history.outcard_history_more
        if history.outcard_history_more
        and history.outcard_history_more[current_round]
        and history.outcard_history_more[current_round][1]
        and history.outcard_history_more[current_round][1].seatid
        and (next_seatid==history.outcard_history_more[current_round][1].seatid) then
            outcard_seat_id = compare_cards()
        else
            outcard_seat_id = next_seatid
        end

        local outcard_info = outcard_logic(outcard_seat_id, cards)
        set_history(outcard_info.seatid, outcard_info.outcard, cards)

        local pos_str = '[pos_'..outcard_info.pos..']'
        local card_s = string.format("0x%04X", outcard_info.outcard)
        log.info(pos_str.." robot play_card:", " seatid="..(outcard_seat_id or "nil")
            .." card="..(card_s or "nil").." trans="..(PUKE_CARDS[outcard_info.outcard] or "nil")
        )
    end

    log.info("finish test_logic! ")

    local read_cards = {
        [1] = {},
        [2] = {},
        [3] = {},
        [4] = {},
    }
    for _, v in ipairs(history.outcard_history_more) do
        for k, _v_ in ipairs(v) do
            local trans = PUKE_CARDS[_v_.outcard]
            if k==1 then
                trans = trans .. "[首出]"
            end
            table.insert(read_cards[tonumber(_v_.seatid)], trans)
        end
    end
    
    log.debug("history=", (read_cards))
end

function M.do_n_test_logic(n)
    n = n or 20
    player_seat_id = 99
    round_ctrl = 14
    for i=1, n do
        call_score_team = math.random(1, 4)
        begin_seatid = call_score_team
        main_color = math.random(1, 4)
        do_test_logic()
        --skynet.sleep(100)
    end
end

return M